First, we need to define a Design Pattern before we can
work with them.Well, a Design Pattern (...affectionately called DP, or DeePee)
can be defined as follows
A
Design Pattern: is the naming and describing of abstract solutions across a
range of recurring design problems
A Pattern
can be defined as: A Model that can be imitated.
Hence a Design pattern is a Model that can be imitated to solve similar design
problems.
A
Pattern is not: meant to facilitate inheritance.
Inheritance is Design-time flexibility. Design Patterns provide run-time
flexibility and solve problems of object role and interactions.
A typical example of a design pattern used repeatedly in
Enterprise DNA solutions we have implemented is the Stateless Object.
later in this class, we will look at the internals of such a stateless object
written in Visual Basic,which will help clarify some of these theoretical
points.
· A Stateless object is loosely
coupled.
· A Stateless object has no attributes,
only methods
· A Stateless object is typically
used in a create-as-needed/destroy-when-done programming
model.
· A Stateless object meets the needs
for scalability and flexibility that are the primary requirments for a
middle-tier in a Web application.
The best way to understand a Stateless Object model is
to compare and contrast it with a typical Stateful Object model common to
client-server applications everywhere.
An example of a Stateful Object model is shown below.
This simple example models the family dynamic centered around a
parent/child/car.
Note the following important points in this design
· All Objects are tightly coupled to
each other
· Parent & Child definitions
inherit from a generic 'Person' definition, as does the 'Car' from 'Vehicle'.
· Objects instantiated using this
model will have the capability of maintaining "State".
o This means we caan set attributes
of a Child and be able to retrieve attributes of it's child, or even the car
whose owner is the parent, etc...
The disadvantages of this design in a Web environment
are as follows:
· In order to create a 'state' using
this model, every attribute of the objects in play needs to be manipulated by
the application. This means one network trip per attribute. This destroys any
scalability hopes we might hope for.
· The interfaces are tightly coupled
at design time, which means that when the objects are deployed they are stuck
with each other.
o So, if the Car object is accessed
more frequently, we cannot move it to another piece of hardware to improve
performance, we have to move the entire family of related objects...
· Extra overhead through
inheritance... even though inheritance promotes good OO practices such as
code-reuse, at run-time, creating an object from a concrete class (e.g. Car)
leads to additional overhead due to the presence of an abstract parent class
('Vehicle')
Redesigning the above Stateful model will give us
something that looks like this
Notice the key differences between this model and the
earlier one
· It's uglier !
· Objects are de-coupled from each
other. There is no obvious relationship between a person and a car. There is,
in fact, no need to create one explicitly.
o Let's say, as part of a
application, we need to model the following process: "User buys car".
To do this, we simplly instantiate a Person object, and invoke the BuyCar
method and give the BuyCar method EVERY scrap of information it needs
to model buying a car. Doing so lets us use the create/destroy
model we talked about earlier.
o Since objects are de-coupled, we
cannot use inheritance
· We have to write more code, since
each method must be told everything it needs to know about a person in the
context of its invocation
· Allows us to deploy frequently used
objects to their own hardware... INSTANT SCALABILITY..!
· Overhead of method invocation is
often lower, because no State information is required to be maintained
Performance and Scalability
are the therefore GODS of Web-based application design.
The success of the
Middle-tier depends on it's ability to scale easily with number of concurrent
users, and it's ability to provide a consistent level of performance throughout
the process of scaling.